/**
*@author Kenneth WU
*@version 17/2/2012
Control Class for update player data
/******************************************
*@author Ming
*@version 11/3/2012
*@Modification: Edited setUP(), add playerOrder(), order(), playerRole() and updateRole()
/******************************************
*@author Syrings
*@version 12/04/2012
*@Modification:Refactoring the switch statement in updatePlayerGrid
it does not need to use switch, just a simple if-else statement can solve it
/*******************************************/

package player;

import board.Board;
import java.util.Random;
import dice.RollDice;

public class PlayerDataProcessor {

	private String[] roleList = { "Gradfather","Gradmother","Father", "Mother","Son","Daughter"};
	private PlayerIO io;
	
	public PlayerDataProcessor() {
		io = new PlayerIO();
	}
	
	/** method that call class Player and Dummy Board Constructor  */
	public void setUp(Player[] playerArr, int numOfPlayer, Board gameBoard) {
		// Create an array of Player base on how numOfPlayer
		//temPArr = new Player[numOfPlayer];
		
		// call DummyBoard constructor
		// temdB = new DummyBoard();
		
		for (int i = 0; i<numOfPlayer; i++) {
			playerArr[i] = new Player();
			playerArr[i].setPlayerID((i+1));
			
			/** method see below*/
			updatePlayerGrid(playerArr[i], gameBoard);
		}
		
		playerOrder(playerArr, numOfPlayer);
		playerRole(playerArr, numOfPlayer);
		
		io.printPlayerArr(playerArr);
	}
	
	/** method to set the order among players  */
	public void playerOrder(Player[] playerArr, int numOfPlayer) {
		int[][] dieResult = new int [numOfPlayer][2];
		
		for (int i=0; i<numOfPlayer; i++)
			dieResult[i][0] = playerArr[i].getPlayerID();
		
		calculateOrder(dieResult, 0, numOfPlayer-1);
		orderPlayer(playerArr, dieResult, numOfPlayer);
		
		/** call to print out the result*/
		io.printOrder(playerArr, numOfPlayer);
	}
	
	private void orderPlayer(Player[] pArr, int[][] dieResult, int numOfPlayer) {
		/** Arrange the array of player according to the order obtained*/
		for (int i=0; i<numOfPlayer; i++) {
			Player temp = new Player();
			int index=-1;
	
			for (int j=i; j<numOfPlayer; j++) {
				if (dieResult[i][0] == pArr[j].getPlayerID()) {
					index=j;
					break;
				}
			}
			
			temp=pArr[i];
			pArr[i]=pArr[index];
			pArr[index]=temp;
		}
	}
		
	private void calculateOrder(int[][] dieResult, int start, int end) {
		RollDice rollDice = new RollDice();
		io.promptRollForOrder(dieResult, start, end);
		for (int i = start; i<=end; i++) {
			dieResult[i][1]= rollDice.roll(dieResult[i][0]);
		}
		orderDieResult (dieResult, start, end);
		sameDieResult (dieResult, start, end);
	}
	
	/** function to the ordering in the specified range
	// Method to determine player order by rolling dice*/
	private void orderDieResult (int[][] dieResult, int start, int end) {
	
		/**Sorting according to dice result of players*/
		for (int i=start; i<=end; i++) {
			int j=i;
			while (j>start && dieResult[j-1][1]<dieResult[j][1]) {
				int[] temp1 = dieResult[j];
				dieResult[j]=dieResult[j-1];
				dieResult[j-1]=temp1;
				j--;
			}
		}
	}
	
	private void sameDieResult(int[][] dieResult, int start, int end) {
		/** Search if users have the same result*/
		for (int i=start; i<end; i++){
			int check = dieResult[i][1];
			int up=0;
			int low=0;
			boolean repeat=false;
			
			for (int j=i+1; j<=end; j++) {
				if (dieResult[j][1] == check) {
					if (repeat)
						up=j;
					else {
						up=j;
						low=j-1;
						repeat=true;
					}
				}
			}
			
			/** Repeat rolling dice if players have same result*/
			if (repeat) {

				io.showRepeat(dieResult, low, up);
				calculateOrder(dieResult, low, up);
				i=up;
			}
		}
	}
	
	/** method that update Player attribute Grid X and Y 
	// Base on DummyBoard attribute cell array 
	// If there is no another Player exist on that cell
	// Player grid x and y appear at the side on the board
	// if there is other player exist, then show up above the existing player*/
	public void updatePlayerGrid(Player p, Board dB){
		/** Temporary variable*/
		int playerCellNum = p.getCell();
	
		/** find out is there any other player exist on that cell*/
		int boardCellNumOfPlayer = dB.getCellArr()[playerCellNum];
		int x = 0;
		int y = 0;
		if(playerCellNum >= 0 && playerCellNum<= 7) {
			x = playerCellNum + 6 ;
			y = 5 - boardCellNumOfPlayer;
		}
		else if(playerCellNum >=8 && playerCellNum <=13){
			x = 15 + boardCellNumOfPlayer;
			y = playerCellNum;
		}
		else if(playerCellNum >= 14 && playerCellNum <=21) {
			x = playerCellNum -((playerCellNum-13)*2 -1);
			y = 15 + boardCellNumOfPlayer;
		}
		else if(playerCellNum >= 22 && playerCellNum <=27) {
			x = 5 - boardCellNumOfPlayer;
			y = 35 - playerCellNum;
		}
		p.setLocation(x, y)	;	
		
		/** Now there is one more player in that cell*/
		dB.getCellArr()[playerCellNum] ++;
	}

	/** To randomly arrange the role card ID*/
	public void playerRole(Player[] pArr, int numOfPlayer){
		int [] roleIDList = new int[6];
		int randomInt;
		
		for (int i=0; i<numOfPlayer; i++) {
			boolean repeat = false;
			do {
				Random randomGenerator = new Random();
				randomInt = randomGenerator.nextInt(6);
				
				for (int j=0; j<i; j++) {
					if (randomInt == roleIDList[j]) {
						repeat = true;
						break;
					}
					else
						repeat = false;
				}	
			} while (repeat);
			roleIDList[i]=randomInt;
		}		
		
		/** invoke the user input to pick the card*/
		io.pickRole(numOfPlayer, pArr, roleIDList);
	}
	
	/** update the role of player and return the role string*/
	public String updateRole(Player p, int index, int[] IDList) {
		String role;
		role = roleList[IDList[index]];
		p.setRole(role);
		return role;
	}
}
